/*
 * enc_osd_mgr.cpp
 *
 *  Created on: 2019年1月5日
 *  Author: Degang.Wu (windragon@126.com)
 *  Desc:
 */
 
#include "ximage.h"

#include "enc_osd_mgr.h"
#include "public.h"
#include "md5.h"
#include "enc_osd.h"


EncHiOSD::EncHiOSD(stENC_OSDSET& osd_set) : u::sys::Thread("EncHiOSD")
{
	memcpy(&this->osd_set, &osd_set, sizeof(stENC_OSDSET));
	osdhash = osd_hash(osd_set);

	// 初始化TTF
	if(TTF_Init() < 0) 
	{
		printf("TTF initial failed\n");
		return ;
	}

}

EncHiOSD::~EncHiOSD()
{
	TTF_Quit();
}

void EncHiOSD::run()
{
	BW_DEBUG("OSD TYPE[%d] begin...", osd_set.osd_type);

	switch (osd_set.osd_type) {
		case BWENC_OSD_TYPE_TEXT:
			show_text();
			break;
		case BWENC_OSD_TYPE_LOGO:
			show_logo();
			break;
		case BWENC_OSD_TYPE_QRCODE:
			show_qr();
			break;
		default:
			break;
	}

	//TODO release stuff...

	BW_DEBUG("OSD TYPE[%d] end", osd_set.osd_type);

}

//停止判断条件：running() == false
void EncHiOSD::show_text()
{
	enc_osd_sub_show(this);

}

void EncHiOSD::show_logo()
{
	enc_osd_logo_show(this);
}

void EncHiOSD::show_qr()
{
	printf("show_qr .....  start\n");
	enc_osd_qr_show(this);
}

U8 EncHiOSD::get_osdtype()
{
	return osd_set.osd_type;
}

std::string EncHiOSD::get_hash()
{
	return osdhash;
}

std::string EncHiOSD::osd_hash(stENC_OSDSET& osd_set)
{
	return u::md5_buffer((unsigned char*)&osd_set.osd_cfg, sizeof(osd_set.osd_cfg));
}

HiOSDMgr::HiOSDMgr() : u::sys::Thread("HiOSDMgr")
{
	// TODO Auto-generated constructor stub
	for (int i = 0; i < ENC_OSD_MAX_OVERLAY; i++)
	{
		osd_threads[i] = NULL;
	}

	// TODO init osd global stuff...

}

HiOSDMgr::~HiOSDMgr()
{
	// TODO Auto-generated destructor stub
}

void HiOSDMgr::run()
{
	while (running())
	{
		schedule_osd();
		Delay(1000);
	}

	// stop osd threads and release
	for (int i = 0; i < ENC_OSD_MAX_OVERLAY; i++)
	{
		if (osd_threads[i])
		{
			osd_threads[i]->tryterminate();
		}
	}

	for (int i = 0; i < ENC_OSD_MAX_OVERLAY; i++)
	{
		if (osd_threads[i])
		{
			osd_threads[i]->terminate();
			SAFE_DELETE_PTR(osd_threads[i]);
		}
	}
}

void HiOSDMgr::schedule_osd()
{
	if (!g_encset_slv || g_chlidx < 0 )
	{
		return;
	}
	stENC_CHLSET& chlset = g_encset_slv->enc_chls[g_chlidx];

	for (int i = 0; i < ENC_OSD_MAX_OVERLAY; i++)
	{
		stENC_OSDSET& osd = chlset.encchl_osd[i];
		//printf("eff = %d i = %d\n", osd_is_effect(osd), i);
		
		if (osd_is_effect(osd))
		{
			if (osd_threads[i])
			{
				//check need reset
				bool reset_flag = false;
				if (osd.osd_type != osd_threads[i]->get_osdtype())
				{
					reset_flag = true;
				}
				else
				{
					// check hash
					std::string hash = EncHiOSD::osd_hash(osd);
					if (hash != osd_threads[i]->get_hash())
					{
						reset_flag = true;
					}
				}

				if (reset_flag)
				{
					// reset osd
					osd_threads[i]->terminate();
					SAFE_DELETE_PTR(osd_threads[i]);

					osd_threads[i] = new EncHiOSD(osd);
					osd_threads[i]->begin();
				}
			}
			else
			{
				// create and start
				osd_threads[i] = new EncHiOSD(osd);
				osd_threads[i]->begin();
			}
		}
		else
		{
			if (osd_threads[i])
			{
				// need stop
				osd_threads[i]->terminate();
				SAFE_DELETE_PTR(osd_threads[i]);
			}
		}
	}
}

bool HiOSDMgr::osd_is_effect(stENC_OSDSET& osd_set)
{
	if (!osd_set.osd_enable)
	{
		return false;
	}

	if (osd_set.osd_type <= BWENC_OSD_TYPE_INVALID || osd_set.osd_type >= BWENC_OSD_TYPE_NB)
	{
		return false;
	}

	// time check
	u::util::U_TIME now_tm;
	u::Util::get_current_time(&now_tm);
	U32 seconds = now_tm.hour * 3600 + now_tm.minute * 60 + now_tm.second;
	int week = now_tm.weekday;
//	printf("second = %d, week = %d\n", seconds, week);

	for (int i = 0; i < ENC_OSD_MAX_TM_NUM; i++)
	{
		if ( (seconds >= osd_set.osd_effect_tm[week][i].tm_start_sec)
				&& (seconds < osd_set.osd_effect_tm[week][i].tm_end_sec))
		{
			return true;
		}
	}

	return false;
}
